# This sample code supports Appium Python client >=2.3.0
# pip install Appium-Python-Client
# Then you can paste this into a file and simply run with Python
import logging
import os
from time import sleep, time
from typing import List

from appium import webdriver
from appium.options.common.base import AppiumOptions
from appium.webdriver.common.appiumby import AppiumBy

# For W3C actions
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.common.actions import interaction
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.support.wait import WebDriverWait
from tomlkit import value

import alipay.util
from alipay import util
from core.common import robot_utils
from core.common.robot_utils import AppiumUtils
from alipay.util import create_directory_if_not_exists


def handle_in_product_info(work_path, title):
    try:
        handle_in_product_info_internal(work_path, title)
    except Exception as e:
        logger.debug(f"获取产品信息失败：{title} {e}")
        # 获取当前时间的毫秒数
        current_milliseconds = int(time() * 1000)
        pngFile = f'./{work_path}/error_{current_milliseconds}_{title}.png'
        driver.save_screenshot(pngFile)


def handle_in_product_info_internal(work_path, title):
    sleep(3)
    logger.debug(f'进入产品详情')
    #  点进产品信息
    handle_in_product_info_for_base_info(work_path, title)
    ##快速回到头部
    appium_utils.swip_header_fast(driver)
    try:
        handle_in_product_info_for_fee_rate_list(work_path, title)
    except Exception as e:
        logger.debug(f"获取费率信息失败")
    ##快速回到头部
    appium_utils.swip_header_fast(driver)
    handle_in_product_info_for_insure_detail(work_path, title)
    status = handle_in_product_info_for_price(work_path, title)
    ##  返回上一页
    el3 = driver.back()
    return status


def handle_in_product_info_for_fee_rate_list(work_path, title):
    """
    ##  获取费率表信息
    :param work_path:
    :param title:
    :return:
    """
    logger.debug(f'handle_in_product_info_for_fee_rate_list')
    swipe_to_find_fee_rate_list(work_path, title)


def handle_in_product_info_for_price(work_path, title):
    """
    ##  获取左下角的价格
    :param work_path:
    :param title:
    :return:
    """
    logger.debug(f'handle_in_product_info_for_price')
    num = 0
    status = 'OK'
    while True:
        elDetailPrice = []
        try:
            sleep(1)
            num = num + 1
            elDetailPrice = driver.find_elements(by=AppiumBy.XPATH,
                                                 value="//android.view.View[@resource-id='INSURE_COMMON_INSURE_BUTTON_CONTAINER']/*")
            if len(elDetailPrice) == 0:
                #  提取类似个人账户无需自费
                elDetailPrice = driver.find_elements(by=AppiumBy.XPATH,
                                                     value="//android.view.View[@resource-id='clauseList']")
                logger.debug(elDetailPrice)
                break
            logger.debug(f'num--->>>>>>>>{num} ---> {elDetailPrice}')
        except Exception as ex:
            # 取不到,说明已经滑过头了
            logger.debug(f'ex:  {ex}')
            sleep(3)
        ## 超过3次机会或者拿到了就跳出
        if num >= 3:
            # 告诉外面说没有拿到
            status = "empty"
            break
        if len(elDetailPrice) > 0:
            break
    if len(elDetailPrice) == 0:
        # 没有取到,退出方法,说明 当前不在产品信息页面
        return
        ## 生成  '|加自选|30.07|元|/月|我要投保'
    priceInfo = '|'.join([itemProduct.text for itemProduct in elDetailPrice])
    logger.debug(priceInfo)
    ############################################################
    return status


def handle_in_product_info_for_base_info(work_path, title):
    """
    ##  获取左下角的价格
    :param work_path:
    :param title:
    :return:
    """
    logger.debug(f'handle_in_product_info_for_base_info')
    appium_utils.swipe_to_bottom_for_screen(work_path, 'base_info')


def handle_in_product_info_for_insure_detail(work_path, title):
    # logger.debug(item)
    ## 进入产品页面
    logger.debug(f'handle_in_product_info_for_insure_detail')
    logger.debug(f'start 更多详情')
    try:
        ##  关闭弹框
        el = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"知道了\")")
        logger.debug(f'关闭弹框')
        el.click()
    except Exception as ex:
        logger.debug(f"关闭弹框")
    moreDetailIcon = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR,
                                         value="new UiSelector().text(\"更多详情\")")
    logger.debug(f'查看更多详情{moreDetailIcon}')
    moreDetailIcon.click()
    appium_utils.swipe_to_bottom_for_screen(work_path, 'insure_detail')
    ##返回
    # backButton = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value = "new UiSelector().resourceId(\"com.alipay.mobile.nebulax.integration:id/frameLayout_backButton\")")
    # backButton.click()
    # logger.debug(f'返回')

    ############################################################

    # 广告
    # el4 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"不用了\")")
    # el4.click()
    driver.back()


def switchForEmpty():
    el3 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"首页\")")
    el3.click()
    el4 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"产品\")")
    el4.click()


def getAllTitle(driver):
    try:
        return driver.find_element(AppiumBy.XPATH, value="//android.widget.TextView[@resource-id='title']").text
    except Exception as ex:
        logger.debug(f"提取title失败:{ex}")
    return 'null'


def swipe_to_find_fee_rate_list(work_path, title):
    while True:
        """打开费率表"""
        try:
            ##  等待资源加载，不然定位不到元素
            sleep(1)
            el4 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"《费率表》\")")
            print(el4)
            el4.click()
            appium_utils.swipe_to_bottom_for_screen(work_path, 'fee_rate_list')
            driver.back()
            break
        except Exception as e:
            logger.debug(f"继续滑动")

        # 获取滑动前页面元素
        before_swipe = driver.page_source
        appium_utils.swipe_up(driver)
        # 获取滑动后页面元素
        after_swipe = driver.page_source
        # 对比滑动前后的页面元素
        # 若滑动前后页面元素完全相同，则滑动失败，已达页尾
        if before_swipe == after_swipe:
            swip_finished = True
            # 若滑动前后页面元素不同，则滑动成功，继续滑动
        else:
            swip_finished = False
        logger.info(f"swip_finished {swip_finished}")
        if swip_finished:
            break


def scroll_product_list(root_dir):
    """
    货架页面滚动
    :return:
    """
    click_target_tab()
    count = 0
    processed_list = []
    page_num = 0
    while True:
        sleep(3)
        title = ''
        try:
            switchForEmpty()
            #  获取产品列表
            logger.debug("获取【蚂蚁保 产品】里面的【产品列表】")
            lists = driver.find_elements(by=AppiumBy.XPATH,
                                         value="//android.view.View[@resource-id='productLCPWrapper']/*")
            count = count + len(lists)
            logger.info(f'产品数量：{count}')
        except Exception as e:
            logger.error(f"遍历失败:{e}")
            break
        # TODO  拿到的可能已经不可见, 获取到的title会为空
        for i in range(len(lists)):
            titleContentList = map(lambda x: getAllTitle(x), lists)
            titleContent = '-'.join(titleContentList)
            logger.debug(f'getAllTitle--->> {i} --->> {titleContent}')
            nullCount = len(list(filter(lambda x: x == 'null', titleContentList)))
            # 跳过为空的
            if (i < nullCount):
                logger.debug(f'跳过为空的--->>  {i} {nullCount}')
                continue
            current = lists[i]
            try:
                if not current.is_displayed():
                    logger.debug(f'元素不可见--->>  {i}')
                    continue
            except Exception as e:
                logger.error(f"元素异常:{e}")
                continue
            sleep(1)
            ##产品名称
            titles = current.find_elements(AppiumBy.XPATH, value="//android.widget.TextView[@resource-id='title']")
            if (len(titles) > 0):
                titleIcon = titles[0]
                title = titleIcon.text
                if processed_list.__contains__(title):
                    logger.debug(f'已处理的{i} \t{title}')
                    if i > 3:
                        driver.drag_and_drop(current, lists[i - 1], 2)
                    continue
                work_path = os.path.join(root_dir, title)
                processed_list.append(title)
                logger.debug(f'index{i},  title:{title}   folder:{work_path}')
                if os.path.exists(work_path):
                    logger.info(f'产品文件已存在， 跳过  {work_path}')
                    if i > 2:
                        driver.drag_and_drop(current, lists[i - 1], 2)
                    continue
                create_directory_if_not_exists(work_path)
                page_num = page_num + 1
                pngFile = f'./{work_path}/referer_{page_num}_{title}.png'
                driver.save_screenshot(pngFile)

                productSummaryInfo = current.find_elements(AppiumBy.XPATH, value="//android.widget.TextView")
                ##  使用价格标签元素 进行跳转，点击进产品详情页面
                productPrice = productSummaryInfo[-1]
                #  提取最后一个,是价格信息: 14.78元起
                productPrice.click()
                if handle_in_product_info(work_path, title) == 'empty':
                    #  未提取到,不能跳转
                    continue

            if i > 2:
                try:
                    driver.drag_and_drop(current, lists[i - 1], 2)
                except Exception as ex:
                    logger.warn("页面滑动失败")


def click_target_tab():
    """"
    点击推荐tab页面，其它先不看
    """
    # 先后点击首页和产品，让推荐 露出
    t1 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"首页\")")
    t1.click()
    t1 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"产品\")")
    t1.click()
    ##  只看推荐的，医疗和意外暂时不看
    t1 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"推荐\")")
    t1.click()


if __name__ == '__main__':
    logger = util.init_logger()
    driver = util.init_driver()
    appium_utils = AppiumUtils(driver, logger)
    ##隐式等待5秒
    ##driver.implicitly_wait(5)
    # 点击首页 我的
    logger.debug("点击【首页】里面【我的】")
    el1 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR,
                              value="new UiSelector().resourceId(\"com.alipay.android.tablauncher:id/tab_icon\").instance(3)")
    el1.click()
    # 点击 我的列表中 [蚂蚁保]
    # el2 = driver.find_element(by=AppiumBy.XPATH,
    #                          value="//android.support.v7.widget.RecyclerView[@resource-id='com.alipay.android.phone.wealth.home:id/asset_home_list']/android.widget.FrameLayout[4]")

    logger.debug("点击【我的】里面【蚂蚁保】")
    el2 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR,
                              value="new UiSelector().className(\"android.view.View\").instance(4)")
    el2.click()
    sleep(3)
    # el3 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"首页\")")
    # el3.click()
    ###############################################################

    logger.debug("点击【蚂蚁保】里面的【产品】")
    el4 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"产品\")")
    logger.debug(f'====================================>{el4}')
    el4.click()
    output_file_path = 'data/product'
    alipay.util.create_directory_if_not_exists(output_file_path)
    ##  等待页面资源加载
    sleep(3)
    driver.save_screenshot(f"./{output_file_path}/test.png")
    # el5 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().resourceId(\"productLCPWrapper\")")
    scroll_product_list(output_file_path)

    # el5.click()
    # el6 = driver.find_element(by=AppiumBy.ANDROID_UIAUTOMATOR, value="new UiSelector().text(\"更多详情\")")
    # el6.click()
    package_name = driver.execute_script('mobile: getCurrentPackage')
    logger.debug(package_name)
    # driver.get_screenshot_as_file('./images/login.png')

    driver.quit()
